/* Copyright (c) 2024 Li Jin, dragon-fly@qq.com

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */

extern "C" {
	fn application_get_frame() -> i32;
	fn application_get_buffer_size() -> i64;
	fn application_get_visual_size() -> i64;
	fn application_get_device_pixel_ratio() -> f32;
	fn application_get_platform() -> i64;
	fn application_get_version() -> i64;
	fn application_get_deps() -> i64;
	fn application_get_delta_time() -> f64;
	fn application_get_elapsed_time() -> f64;
	fn application_get_total_time() -> f64;
	fn application_get_running_time() -> f64;
	fn application_get_rand() -> i64;
	fn application_get_max_fps() -> i32;
	fn application_is_debugging() -> i32;
	fn application_set_locale(var: i64);
	fn application_get_locale() -> i64;
	fn application_set_theme_color(var: i32);
	fn application_get_theme_color() -> i32;
	fn application_set_seed(var: i32);
	fn application_get_seed() -> i32;
	fn application_set_target_fps(var: i32);
	fn application_get_target_fps() -> i32;
	fn application_set_win_size(var: i64);
	fn application_get_win_size() -> i64;
	fn application_set_win_position(var: i64);
	fn application_get_win_position() -> i64;
	fn application_set_fps_limited(var: i32);
	fn application_is_fps_limited() -> i32;
	fn application_set_idled(var: i32);
	fn application_is_idled() -> i32;
	fn application_set_full_screen(var: i32);
	fn application_is_full_screen() -> i32;
	fn application_set_always_on_top(var: i32);
	fn application_is_always_on_top() -> i32;
	fn application_shutdown();
}
/// A struct representing an application.
pub struct App { }
impl App {
	/// Gets the current passed frame number.
	pub fn get_frame() -> i32 {
		return unsafe { application_get_frame() };
	}
	/// Gets the size of the main frame buffer texture used for rendering.
	pub fn get_buffer_size() -> crate::dora::Size {
		return unsafe { crate::dora::Size::from(application_get_buffer_size()) };
	}
	/// Gets the logic visual size of the screen.
	/// The visual size only changes when application window size changes.
	/// And it won't be affacted by the view buffer scaling factor.
	pub fn get_visual_size() -> crate::dora::Size {
		return unsafe { crate::dora::Size::from(application_get_visual_size()) };
	}
	/// Gets the ratio of the pixel density displayed by the device
	/// Can be calculated as the size of the rendering buffer divided by the size of the application window.
	pub fn get_device_pixel_ratio() -> f32 {
		return unsafe { application_get_device_pixel_ratio() };
	}
	/// Gets the platform the game engine is running on.
	pub fn get_platform() -> String {
		return unsafe { crate::dora::to_string(application_get_platform()) };
	}
	/// Gets the version string of the game engine.
	/// Should be in format of "v0.0.0".
	pub fn get_version() -> String {
		return unsafe { crate::dora::to_string(application_get_version()) };
	}
	/// Gets the dependencies of the game engine.
	pub fn get_deps() -> String {
		return unsafe { crate::dora::to_string(application_get_deps()) };
	}
	/// Gets the time in seconds since the last frame update.
	pub fn get_delta_time() -> f64 {
		return unsafe { application_get_delta_time() };
	}
	/// Gets the elapsed time since current frame was started, in seconds.
	pub fn get_elapsed_time() -> f64 {
		return unsafe { application_get_elapsed_time() };
	}
	/// Gets the total time the game engine has been running until last frame ended, in seconds.
	/// Should be a contant number when invoked in a same frame for multiple times.
	pub fn get_total_time() -> f64 {
		return unsafe { application_get_total_time() };
	}
	/// Gets the total time the game engine has been running until this field being accessed, in seconds.
	/// Should be a increasing number when invoked in a same frame for multiple times.
	pub fn get_running_time() -> f64 {
		return unsafe { application_get_running_time() };
	}
	/// Gets a random number generated by a random number engine based on Mersenne Twister algorithm.
	/// So that the random number generated by a same seed should be consistent on every platform.
	pub fn get_rand() -> i64 {
		return unsafe { application_get_rand() };
	}
	/// Gets the maximum valid frames per second the game engine is allowed to run at.
	/// The max FPS is being inferred by the device screen max refresh rate.
	pub fn get_max_fps() -> i32 {
		return unsafe { application_get_max_fps() };
	}
	/// Gets whether the game engine is running in debug mode.
	pub fn is_debugging() -> bool {
		return unsafe { application_is_debugging() != 0 };
	}
	/// Sets the system locale string, in format like: `zh-Hans`, `en`.
	pub fn set_locale(var: &str) {
		unsafe { application_set_locale(crate::dora::from_string(var)) };
	}
	/// Gets the system locale string, in format like: `zh-Hans`, `en`.
	pub fn get_locale() -> String {
		return unsafe { crate::dora::to_string(application_get_locale()) };
	}
	/// Sets the theme color for Dora SSR.
	pub fn set_theme_color(var: &crate::dora::Color) {
		unsafe { application_set_theme_color(var.to_argb() as i32) };
	}
	/// Gets the theme color for Dora SSR.
	pub fn get_theme_color() -> crate::dora::Color {
		return unsafe { crate::dora::Color::from(application_get_theme_color()) };
	}
	/// Sets the random number seed.
	pub fn set_seed(var: i32) {
		unsafe { application_set_seed(var) };
	}
	/// Gets the random number seed.
	pub fn get_seed() -> i32 {
		return unsafe { application_get_seed() };
	}
	/// Sets the target frames per second the game engine is supposed to run at.
	/// Only works when `fpsLimited` is set to true.
	pub fn set_target_fps(var: i32) {
		unsafe { application_set_target_fps(var) };
	}
	/// Gets the target frames per second the game engine is supposed to run at.
	/// Only works when `fpsLimited` is set to true.
	pub fn get_target_fps() -> i32 {
		return unsafe { application_get_target_fps() };
	}
	/// Sets the application window size.
	/// May differ from visual size due to the different DPIs of display devices.
	/// It is not available to set this property on platform Android and iOS.
	pub fn set_win_size(var: &crate::dora::Size) {
		unsafe { application_set_win_size(var.into_i64()) };
	}
	/// Gets the application window size.
	/// May differ from visual size due to the different DPIs of display devices.
	/// It is not available to set this property on platform Android and iOS.
	pub fn get_win_size() -> crate::dora::Size {
		return unsafe { crate::dora::Size::from(application_get_win_size()) };
	}
	/// Sets the application window position.
	/// It is not available to set this property on platform Android and iOS.
	pub fn set_win_position(var: &crate::dora::Vec2) {
		unsafe { application_set_win_position(var.into_i64()) };
	}
	/// Gets the application window position.
	/// It is not available to set this property on platform Android and iOS.
	pub fn get_win_position() -> crate::dora::Vec2 {
		return unsafe { crate::dora::Vec2::from(application_get_win_position()) };
	}
	/// Sets whether the game engine is limiting the frames per second.
	/// Set `fpsLimited` to true, will make engine run in a busy loop to track the  precise frame time to switch to the next frame. And this behavior can lead to 100% CPU usage. This is usually common practice on Windows PCs for better CPU usage occupation. But it also results in extra heat and power consumption.
	pub fn set_fps_limited(var: bool) {
		unsafe { application_set_fps_limited(if var { 1 } else { 0 }) };
	}
	/// Gets whether the game engine is limiting the frames per second.
	/// Set `fpsLimited` to true, will make engine run in a busy loop to track the  precise frame time to switch to the next frame. And this behavior can lead to 100% CPU usage. This is usually common practice on Windows PCs for better CPU usage occupation. But it also results in extra heat and power consumption.
	pub fn is_fps_limited() -> bool {
		return unsafe { application_is_fps_limited() != 0 };
	}
	/// Sets whether the game engine is currently idled.
	/// Set `idled` to true, will make game logic thread use a sleep time and going idled for next frame to come. Due to the imprecision in sleep time. This idled state may cause game engine over slept for a few frames to lost.
	/// `idled` state can reduce some CPU usage.
	pub fn set_idled(var: bool) {
		unsafe { application_set_idled(if var { 1 } else { 0 }) };
	}
	/// Gets whether the game engine is currently idled.
	/// Set `idled` to true, will make game logic thread use a sleep time and going idled for next frame to come. Due to the imprecision in sleep time. This idled state may cause game engine over slept for a few frames to lost.
	/// `idled` state can reduce some CPU usage.
	pub fn is_idled() -> bool {
		return unsafe { application_is_idled() != 0 };
	}
	/// Sets whether the game engine is running in full screen mode.
	/// It is not available to set this property on platform Android and iOS.
	pub fn set_full_screen(var: bool) {
		unsafe { application_set_full_screen(if var { 1 } else { 0 }) };
	}
	/// Gets whether the game engine is running in full screen mode.
	/// It is not available to set this property on platform Android and iOS.
	pub fn is_full_screen() -> bool {
		return unsafe { application_is_full_screen() != 0 };
	}
	/// Sets whether the game engine window is always on top. Default is true.
	/// It is not available to set this property on platform Android and iOS.
	pub fn set_always_on_top(var: bool) {
		unsafe { application_set_always_on_top(if var { 1 } else { 0 }) };
	}
	/// Gets whether the game engine window is always on top. Default is true.
	/// It is not available to set this property on platform Android and iOS.
	pub fn is_always_on_top() -> bool {
		return unsafe { application_is_always_on_top() != 0 };
	}
	/// Shuts down the game engine.
	/// It is not working and acts as a dummy function for platform Android and iOS to follow the specification of how mobile platform applications should operate.
	pub fn shutdown() {
		unsafe { application_shutdown(); }
	}
}